package com.jzcn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jzcn.common.base.BaseServiceImpl;
import com.jzcn.common.dto.common.LabelValueDTO;
import com.jzcn.common.dto.system.user.SearchUserDTO;
import com.jzcn.common.dto.system.user.SysUserDTO;
import com.jzcn.common.dto.system.user.UserListDTO;
import com.jzcn.common.exceptions.BusinessException;
import com.jzcn.common.utils.BeanUtils;
import com.jzcn.common.utils.JzPage;
import com.jzcn.common.utils.Md5Utils;
import com.jzcn.domain.SysRole;
import com.jzcn.domain.SysUser;
import com.jzcn.domain.SysUserRole;
import com.jzcn.mapper.SysUserMapper;
import com.jzcn.service.SysRoleService;
import com.jzcn.service.SysUserRoleService;
import com.jzcn.service.SysUserService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends BaseServiceImpl<SysUserMapper, SysUser> implements SysUserService {

    @Value("${common.password}")
    private String pwd;

    @Resource
    private SysUserRoleService sysUserRoleService;

    @Resource
    private SysRoleService sysRoleService;

    @Override
    public boolean delete(Integer id) {
        return super.removeById(id);
    }

    @Override
    public SysUser getInfo(Integer id) {
        return super.getById(id);
    }

    @Override
    public SysUser getUserName(String userName) {
        return this.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, userName));
    }

    @Override
    public boolean newPassword(Integer id, String oldPassword, String newPassword) {
        SysUser sysUser = super.getById(id);
        String password = Md5Utils.hash(oldPassword);
        if(!sysUser.getPassword().equals(password)){
            throw new BusinessException("原始密码有误！");
        }
        sysUser.setId(id);
        sysUser.setPassword(Md5Utils.hash(newPassword));
        return this.update(sysUser);
    }

    @Override
    public boolean resetPwd(Integer id) {
        SysUser sysUser = super.getById(id);
        String password = Md5Utils.hash(pwd);
        sysUser.setPassword(password);
        return this.update(sysUser);
    }

    @Override
    public boolean userStatus(Integer id, Integer status) {
        SysUser sysUser = super.getById(id);
        sysUser.setStatus(status);
        return this.update(sysUser);
    }


    @Override
    public JzPage<UserListDTO> listPage(SearchUserDTO searchUser) {
        IPage<SysUser> iPage = new Page<>(searchUser.getPageNum(), searchUser.getPageSize());
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(StringUtils.isNotEmpty(searchUser.getUserName()),SysUser::getUserName,searchUser.getUserName());
        JzPage<UserListDTO> page = BeanUtils.convertPage(new JzPage<>(baseMapper.selectPage(iPage,wrapper)), UserListDTO.class);
        List<SysUserRole> userRoles  = sysUserRoleService.list();
        Map<Integer, String> sysRoles = sysRoleService.list().stream().collect(Collectors.toMap(SysRole::getId,SysRole::getName));
        Map<Integer,List<SysUserRole>> getUserRoles= userRoles.stream().collect(Collectors.groupingBy(SysUserRole::getUserId));
        page.getList().forEach(el->{
            List<LabelValueDTO> roles = new ArrayList<>();
            List<SysUserRole> sysUserRole = getUserRoles.get(el.getId());
            if(!CollectionUtils.isEmpty(sysUserRole)) {
                sysUserRole.forEach(role->{
                    java.lang.String nameRole = sysRoles.get(role.getRoleId());
                    LabelValueDTO labelValueDTO = new LabelValueDTO();
                    labelValueDTO.setLabel(nameRole);
                    labelValueDTO.setValue(role.getRoleId().toString());
                    roles.add(labelValueDTO);
                });
            }
            el.setRoles(roles);
        });
        return page;
    }

    @Override
    public SysUser login(String userName, String password) {
        //LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        SysUser sysUser = getUserName(userName);
        if(Objects.isNull(sysUser)){
            throw new BusinessException("用户名不存在");
        }
        checkUserPwd(sysUser,password);
        return sysUser;
    }

    @Override
    public boolean create(SysUserDTO sysUserDTO){
        if(super.checkUniqueness("user_name",sysUserDTO.getUserName())){
            throw new BusinessException("用户名称已存在");
        }
       SysUser sysUser = saveOrUpdate(sysUserDTO);
        if(super.save(sysUser)){
            inserUserRole(sysUserDTO.getRoles(),sysUser.getId());
            return true;
        }
        return false;
    }

    @Override
    public boolean update(SysUserDTO sysUserDTO,Integer id) {
        SysUser sysUser = saveOrUpdate(sysUserDTO);
        sysUser.setId(id);
        if(super.update(sysUser)){
            sysUserRoleService.remove(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, sysUser.getId()));
            inserUserRole(sysUserDTO.getRoles(),sysUser.getId());
            return true;
        }
        return false;
    }

    private SysUser saveOrUpdate(SysUserDTO sysUserDTO){
        SysUser users = new SysUser();
        BeanUtils.copyProperties(sysUserDTO,users);
        if(!StringUtils.isEmpty(users.getPassword())){
          String password =  Md5Utils.hash(users.getPassword());
          users.setPassword(password);
        }
        return users;
    }

    /**
     * @param sysUser
     * @param password  用户输入的密码
     */
    private void checkUserPwd(SysUser sysUser, String password) {
        String encryptPwd = Md5Utils.hash(password);
        // log.info("用户密码为：{}", encryptPwd);
        if (!sysUser.getPassword().equalsIgnoreCase(encryptPwd)) {
            throw new BusinessException("您输入的密码有误");
        }
    }

    private void inserUserRole(List<Integer> roles,Integer userId){
        if (CollectionUtils.isNotEmpty(roles)) {
            List<SysUserRole> sysUserRoles = new ArrayList<>();
            for (Integer roleId : roles) {
                SysUserRole sysUserRole = new SysUserRole();
                sysUserRole.setRoleId(roleId);
                sysUserRole.setUserId(userId);
                sysUserRoles.add(sysUserRole);
            }
            sysUserRoleService.saveBatch(sysUserRoles);
        }
    }

}
